#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

class Base
{
//public:
protected:
    //默认构造函数就是无参构造函数
    Base()
    : _data(new char[1]())
    {   cout << "Base()" << endl;   }

    Base(const char * data)
    : _data(new char[strlen(data) + 1]())
    {   
        cout << "Base( const char* )" << endl;   
        strcpy(_data, data);
    }

    Base(const Base & rhs)
    : _data(new char[strlen(rhs._data) + 1]())
    {   
        cout << "Base(const Base&)" << endl;
        strcpy(_data, rhs._data);
    }

protected:
    Base & operator=(const Base & rhs)
    {
        cout << "Base & operator=(const Base&)" << endl;
        if(this != &rhs) {
            delete [] _data;
            _data = new char[strlen(rhs._data) + 1]();
            strcpy(_data, rhs._data);
        }
        return *this;
    }

    friend ostream & operator<<(ostream &os, const Base & rhs);

private:
    char * _data;
};
    
ostream & operator<<(ostream &os, const Base & rhs)
{
    os << rhs._data;
    return os;
}

class Derived
: public Base
{
public:
    Derived(const char * data, const char * data2)
    : Base(data)
    , _data2(new char[strlen(data2) + 1]())
    {   
        cout << "Derived(const char *)" << endl;   
        strcpy(_data2, data2);
    }

    //派生类的拷贝构造函数默认情况下要初始化基类部分，
    //只会调用基类默认构造函数
    Derived(const Derived &rhs)
    //: Base()
    : Base(rhs) //手动调用  const Base & r = rhs;
    , _data2(new char[strlen(rhs._data2) + 1]())
    {
        strcpy(_data2, rhs._data2);
        cout << "Derived(const Derived &)" << endl;
    }

    Derived & operator=(const Derived & rhs)
    {
        cout << "Derived & operator=(const Derived&)" << endl;
        if(this != &rhs){
            //this解释成Base的指针
            //(Base&)*this = rhs;
            this->Base::operator=(rhs);//const Base & r = rhs;
            //((Base*)this)->operator=(rhs);//手动调用
            delete [] _data2;
            _data2 = new char[strlen(rhs._data2) + 1]();
            strcpy(_data2, rhs._data2);
        }
        return *this;
    }

    //2. 当派生类有显式定义复制控制函数，执行派生类间对象的复制控制操作时，
    //对于基类部分的复制控制函数不会自动调用,必须手动调用

    friend ostream &operator<<(ostream &os, const Derived & rhs);
private:
    char * _data2;
};

ostream &operator<<(ostream &os, const Derived & rhs)
{
    os << (Base&)rhs << ", derived:" << rhs._data2;
    return os;
}

void test0()
{
    Derived d1("hello", "world");
    //派生类对象可以转换为基类对象
    cout << "d1:" << d1 << endl;
    Derived d2 = d1;
    cout << "d2:" << d2 << endl << endl;

#if 1
    Derived d3("wuhan", "wangdao");
    cout << "d3:" << d3 << endl;
    d3 = d1;
    cout << "d3:" << d3 << endl;
#endif

}

int main()
{
    test0();
    return 0;
}

